﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Threading;
using System.Net;
using System.Collections;
using System.Runtime.Serialization;
using M7;
using System.Windows;
using S7.UserControls;

namespace S7
{
    public class ClientConnection:IEquatable<ClientConnection>
    {
        public CurrentInfo current = new CurrentInfo();
        public Thread thrRead;
        public Queue<Msg> ReadingQueue = new Queue<Msg>();

        //private Enum Ack(Msg msg)
        //{
        //    Enum operationType = null;
        //    if (msg.enumMethod is enumBooking)
        //    {
        //        enumBooking method = (enumBooking)msg.enumMethod;
        //        switch (method)
        //        {
        //            case enumBooking.BookingAdd:
        //                {
        //                    operationType = enumAck.AckBookingAdd;
        //                    break;
        //                }
        //            case enumBooking.BookingCancel:
        //                {
        //                    operationType = enumAck.AckBookingCancel;
        //                    break;
        //                }
        //            case enumBooking.BookingDelete:
        //                {
        //                    operationType = enumAck.AckBookingDelete;
        //                    break;
        //                }
        //            case enumBooking.BookingEdit:
        //                {
        //                    operationType = enumAck.AckBookingEdit;
        //                    break;
        //                }
        //        }
        //    }
        //    else if (msg.enumMethod is enumChat)
        //    {
        //        enumChat method = (enumChat)msg.enumMethod;
        //        switch (method)
        //        {
        //            case enumChat.ChatConnect:
        //                {
        //                    operationType = enumAck.AckChatConnect;
        //                    break;
        //                }
        //            case enumChat.ChatDisconnect:
        //                {
        //                    operationType = enumAck.AckChatDisconnect;
        //                    break;
        //                }
        //            case enumChat.ChatSend:
        //                {
        //                    operationType = enumAck.AckChatSend;
        //                    break;
        //                }
        //            case enumChat.ChatReceiveMsg:
        //                {
        //                    operationType = enumAck.AckChatReceiveMsg;
        //                    break;
        //                }
        //        }
        //    }
        //    else if (msg.enumMethod is enumConnection)
        //    {
        //        enumConnection method = (enumConnection)msg.enumMethod;
        //        switch (method)
        //        {
        //            case enumConnection.ConnectionConnect:
        //                {
        //                    operationType = enumAck.AckConnectionConnect;
        //                    break;
        //                }
        //            case enumConnection.ConnectionDisconnect:
        //                {
        //                    operationType = enumAck.AckConnectionDisconnect;
        //                    break;
        //                }
        //        }
        //    }
        //    else if (msg.enumMethod is enumCustomer)
        //    {
        //        enumCustomer method = (enumCustomer)msg.enumMethod;
        //        switch (method)
        //        {
        //            case enumCustomer.CustomerDelete:
        //                {
        //                    operationType = enumAck.AckCustomerDelete;
        //                    break;
        //                }
        //            case enumCustomer.CustomerSignIn:
        //                {
        //                    operationType = enumAck.AckCustomerSignIn;
        //                    break;
        //                }
        //            case enumCustomer.CustomerSignOut:
        //                {
        //                    operationType = enumAck.AckCustomerSignOut;
        //                    break;
        //                }
        //            case enumCustomer.CustomerSignUp:
        //                {
        //                    operationType = enumAck.AckCustomerSignUp;
        //                    break;
        //                }
        //        }
        //    }
        //    else if (msg.enumMethod is enumFavorite)
        //    {
        //        enumFavorite method = (enumFavorite)msg.enumMethod;
        //        switch (method)
        //        {
        //            case enumFavorite.FavoriteAdd:
        //                {
        //                    operationType = enumAck.AckFavoriteAdd;
        //                    break;
        //                }
        //            case enumFavorite.FavoriteDelete:
        //                {
        //                    operationType = enumAck.AckFavoriteDelete;
        //                    break;
        //                }
        //        }
        //    }
        //    else if (msg.enumMethod is enumFeedback)
        //    {
        //        enumFeedback method = (enumFeedback)msg.enumMethod;
        //        switch (method)
        //        {
        //            case enumFeedback.FeedbackAdd:
        //                {
        //                    operationType = enumAck.AckFeedbackAdd;
        //                    break;
        //                }
        //        }
        //    }
        //    else if (msg.enumMethod is enumMenuItem)
        //    {
        //        enumMenuItem method = (enumMenuItem)msg.enumMethod;
        //        switch (method)
        //        {
        //            case enumMenuItem.MenuItemsSearch:
        //                {
        //                    operationType = enumAck.AckMenuItemsSearch;
        //                    break;
        //                }
        //        }
        //    }
        //    else if (msg.enumMethod is enumMenus)
        //    {
        //        enumMenus method = (enumMenus)msg.enumMethod;
        //        switch (method)
        //        {
        //            case enumMenus.MenusSearch:
        //                {
        //                    operationType = enumAck.AckMenusSearch;
        //                    break;
        //                }
        //        }
        //    }
        //    else if (msg.enumMethod is enumOrder)
        //    {
        //        enumOrder method = (enumOrder)msg.enumMethod;
        //        switch (method)
        //        {
        //            case enumOrder.OrderAdd:
        //                {
        //                    operationType = enumAck.AckOrderAdd;
        //                    break;
        //                }
        //        }
        //    }
        //    return operationType;
        //}

        private void ShowMessage(string Message)
        {
            Info.window.Dispatcher.Invoke(new ThreadStart(() =>
                    {
                        var chairs = from table in Info.window.wrpLiveView.Children.OfType<TableControl>()
                                     from chair in table.rpChairs.Children.OfType<Chair>()
                                     where chair.CustomerID.Equals(current.CustomerID)
                                     select chair;
                        foreach (var chair in chairs)
                        {
                            chair.ShowMessage(Message);
                        }
                    }));
        }

        public void ChangeColor(Chair.Waiting w)
        {
            Info.window.Dispatcher.Invoke(new ThreadStart(() =>
                    {
                        var tables = from table in Info.window.wrpLiveView.Children.OfType<TableControl>()
                                     where table.Connection != null 
                                     && table.Connection.Equals(this)
                                     select table;
                        foreach (var item in tables)
                        {
                            item.ChangeColor(w);
                            break;
                        }

                        var chairs = from table in Info.window.wrpLiveView.Children.OfType<TableControl>()
                                     from chair in table.rpChairs.Children.OfType<Chair>()
                                     where chair.CustomerID == table.Connection.current.CustomerID
                                     select chair;
                        foreach (var item in chairs)
                        {
                            item.ChangeColor(w);
                        }
                    }));
        }

        private void SetVotes(NVote vote)
        {
            var genres = from genre in Info.MusicVotes.Keys.ToList()
                         where genre.GenreName.Equals(vote.Genre)
                         select genre;
            foreach (var genre in genres)
            {
                Info.MusicVotes[genre]++;
            }

            var TVs = from tv in Info.TVVotes.Keys.ToList()
                         where tv.ChannelName.Equals(vote.TV)
                         select tv;
            foreach (var tv in TVs)
            {
                Info.TVVotes[tv]++;
            }

            var ACs = from ac in Info.ACVotes.Keys.ToList()
                      where ac.Temp.Equals(vote.ACTemp)
                         select ac;
            foreach (var ac in ACs)
            {
                Info.ACVotes[ac]++;
            }
        }


        public void Disconnect()
        {
            Info.window.Dispatcher.Invoke(new ThreadStart(() =>
            {
                try
                {
                    var tables = from table in Info.window.wrpLiveView.Children.OfType<TableControl>()
                                 where table.Connection != null
                                 && table.Connection.Equals(this)
                                 select table;
                    foreach (var item in tables)
                    {
                        item.rpChairs.Children.Clear();
                        item.Info1 = "";
                        item.Info2 = "";
                        item.Info3 = "";
                        item.Info4 = "";
                        break;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }));

            ChangeColor(Chair.Waiting.Offline);
        }

        #region ReadingMethods
        public void ReadClass()
        {
            while (true)
            {
                if (ReadingQueue.Count != 0)
                {
                    Msg msg = ReadingQueue.Dequeue();
                    if (msg.Start == "~~" && msg.End == "~~")
                    {
                        if (msg.enumMethod is enumAck)
                        {
                            //Ack Received
                        }
                        else
                        {
                            //Send Ack
                            if (msg.enumMethod is enumBooking)
                            {
                                ReadBooking(msg);
                            }
                            else if (msg.enumMethod is enumChat)
                            {
                                ReadChat(msg);
                            }
                            else if (msg.enumMethod is enumConnection)
                            {
                                ReadConnection(msg);
                            }
                            else if (msg.enumMethod is enumCustomer)
                            {
                                ReadCustomer(msg);
                            }
                            else if (msg.enumMethod is enumFavorite)
                            {
                                ReadFavorite(msg);
                            }
                            else if (msg.enumMethod is enumFeedback)
                            {
                                ReadFeedback(msg);
                            }
                            else if (msg.enumMethod is enumMenuItem)
                            {
                                ReadMenuItem(msg);
                            }
                            else if (msg.enumMethod is enumMenus)
                            {
                                ReadMenus(msg);
                            }
                            else if (msg.enumMethod is enumOrder)
                            {
                                ReadOrder(msg);
                            }
                            else if (msg.enumMethod is enumPersonalization)
                            {
                                ReadPersonalization(msg);
                            }
                            else if(msg.enumMethod is enumRequests)
                            {
                                ReadRequests(msg);
                            }
                            else if (msg.enumMethod is enumAdminTools)
                            {
                                ReadAdminTools(msg);
                            }
                            else if(msg.enumMethod is enumInternet)
                            {
                                ReadInternet(msg);
                            }
                            else if (msg.enumMethod is enumMusic)
                            {
                                ReadMusic(msg);
                            }
                            else if (msg.enumMethod is MessageBoxButton)
                            {
                                ReadMessageBox(msg);
                            }
                        }
                    }
                    else
                    {
                        //Error Receiving Msg
                    }  
                }
                else
                {
                    //No Msg Received
                    Thread.Sleep(200);
                }
            }
        }

        private void ReadMessageBox(Msg msg)
        {
            MessageBoxButton method = (MessageBoxButton)msg.enumMethod;
            switch (method)
            {
                case MessageBoxButton.OK:
                    {
                        this.current.CustomerID = (int)msg.obj;

                        Info.window.Dispatcher.Invoke(new ThreadStart(() =>
                        {
                            try
                            {
                                var Tables = from tb in Info.window.wrpLiveView.Children.OfType<TableControl>()
                                             from cust in current.customers
                                             where tb.Connection != null
                                             && tb.Connection == this
                                             && cust.CustomerID == this.current.CustomerID
                                             select new { tb, cust };

                                foreach (var item in Tables)
                                {
                                    item.tb.Info1 = item.cust.Username;
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
                            }
                        }), null);

                        break;
                    }
                case MessageBoxButton.OKCancel:
                    {
                        Msg SendMsg = new Msg();
                        SendMsg.IP = msg.IP;
                        SendMsg.port = msg.port;
                        SendMsg.obj = Info.News;
                        SendMsg.enumMethod = MessageBoxButton.OKCancel;
                        Info.server.SendingQueue.Enqueue(SendMsg);
                        break;
                    }
                case MessageBoxButton.YesNo:
                    {
                        ChangeColor(Chair.Waiting.Cab);
                        break;
                    }
                case MessageBoxButton.YesNoCancel:
                    {
                        break;
                    }
            }
        }

        private void ReadMusic(Msg msg)
        {
            enumMusic method = (enumMusic)msg.enumMethod;
            switch (method)
            {
                case enumMusic.Lyrics:
                    {
                        Msg SendMsg = new Msg();
                        SendMsg.IP = msg.IP;
                        SendMsg.port = msg.port;
                        SendMsg.obj = Info.CurrentSong;
                        Info.server.SendingQueue.Enqueue(SendMsg);
                        break;
                    }
            }
        }

        private void ReadInternet(Msg msg)
        {
            enumInternet method = (enumInternet)msg.enumMethod;
            switch (method)
            {
                case enumInternet.Website:
                    {
                        ShowMessage(msg.obj.ToString());
                        break;
                    }
            }
        }

        private void ReadRequests(Msg msg)
        {
            enumRequests method = (enumRequests)msg.enumMethod;
            switch (method)
            {
                case enumRequests.CallWaiter:
                    {
                        ShowMessage("Waiter please?");
                        ChangeColor(Chair.Waiting.Waiter);
                        break;
                    }
                case enumRequests.MaleWC:
                    {
                        NCustomer nCust = (NCustomer)msg.obj;
                        if (Info.MalesQueue == null)
                        {
                            Info.MalesQueue = new Queue<NCustomer>();
                        }
                        Info.MalesQueue.Enqueue(nCust);
                        ChangeColor(Chair.Waiting.WC);
                        break;
                    }
                case enumRequests.FemaleWC:
                    {
                        NCustomer nCust = (NCustomer)msg.obj;
                        if (Info.FemalesQueue == null)
                        {
                            Info.FemalesQueue = new Queue<NCustomer>();
                        }
                        Info.FemalesQueue.Enqueue(nCust);
                        ChangeColor(Chair.Waiting.WC);
                        break;
                    }
            }
        }

        private void ReadConnection(Msg msg)
        {
            enumConnection method = (enumConnection)msg.enumMethod;
            switch (method)
            {
                case enumConnection.ConnectionConnect:
                    {
                        ChangeColor(Chair.Waiting.Online);
                        var tables = from table in Table.lstTables
                                     where table.TableID.Equals(current.TableID)
                                     select table;
                        foreach (var table in tables)
                        {
                            table.IP = current.IP.ToString();
                            table.Port = current.Port;
                            table.Edit();
                        }
                        break;
                    }
                case enumConnection.ConnectionDisconnect:
                    {
                        Disconnect();
                        break;
                    }
            }
        }

        private void ReadChat(Msg msg)
        {
            ChatClient c = (ChatClient)msg.obj;
            enumChat method = (enumChat)msg.enumMethod;
            Msg SendMsg = new Msg();
            SendMsg.IP = msg.IP;
            SendMsg.port = msg.port;
            switch (method)
            {
                case enumChat.ChatConnect:
                    {
                        SendMsg.enumMethod = enumChat.ChatConnect;
                        SendMsg.Succeeded = ChatServer.AddClient(c);
                        break;
                    }
                case enumChat.ChatDisconnect:
                    {
                        SendMsg.enumMethod = enumChat.ChatDisconnect;
                        SendMsg.Succeeded = ChatServer.RemoveClient(c);
                        break;
                    }
                case enumChat.ChatSend:
                    {
                        SendMsg.enumMethod = enumChat.ChatSend;
                        ChatServer.ChatMsgs.Add(c);
                        if (Info.showChatWindow != null)
                        {
                            Info.window.Dispatcher.Invoke(new ThreadStart(() =>
                               {
                                   Info.showChatWindow.lbChat.ItemsSource = null;
                                   Info.showChatWindow.lbChat.ItemsSource = ChatServer.ChatMsgs;
                               }));
                        }
                        else if (Info.enterChatWindow != null)
                        {
                            Info.window.Dispatcher.Invoke(new ThreadStart(() =>
                                {
                                    Info.enterChatWindow.lbChat.ItemsSource = null;
                                    Info.enterChatWindow.lbChat.ItemsSource = ChatServer.ChatMsgs;
                                }));
                        }
                        SendMsg.Succeeded = ChatServer.SendToClients(c);
                        break;
                    }
            }
            //Info.server.SendingQueue.Enqueue(SendMsg);
        }

        private void ReadCustomer(Msg msg)
        {
            NCustomer obj = (NCustomer)msg.obj;
            Customer cust = new Customer(obj);
            enumCustomer method = (enumCustomer)msg.enumMethod;
            string error = null;
            Msg SendMsg = new Msg();
            SendMsg.IP = msg.IP;
            SendMsg.port = msg.port;
            switch (method)
            {
                case enumCustomer.CustomerSignUp:
                    {
                        error = cust.SignUp();
                        SendMsg.enumMethod = enumCustomer.CustomerSignUp;
                        if (error == "")
                        {
                            SendMsg.Succeeded = true;
                            SendMsg.obj = cust;
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
                case enumCustomer.CustomerSignIn:
                    {
                        error = cust.SignIn();
                        SendMsg.enumMethod = enumCustomer.CustomerSignIn;
                        if (error == "")
                        {
                            SendMsg.Succeeded = true;
                            obj.CustomerID = cust.CustomerID;
                            SendMsg.obj = obj;
                            this.current.customers.Add(obj);
                            current.CustomerID = cust.CustomerID;
                            Info.window.Dispatcher.Invoke(new ThreadStart(() =>
                                {
                                    try
                                    {
                                        foreach (TableControl tb in Info.window.wrpLiveView.Children)
                                        {
                                            if (tb.Connection != null && tb.Connection.Equals(this))
                                            {
                                                tb.AddChair(cust.UserName, cust.CustomerID);
                                                tb.Info1 = cust.UserName;
                                                break;
                                            }
                                        }
                                        ShowMessage("Hi!");
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageBox.Show(ex.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
                                    }
                                }), null);
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
                case enumCustomer.CustomerSignOut:
                    {
                        error = cust.SignOut();
                        SendMsg.enumMethod = enumCustomer.CustomerSignOut;
                        if (error == "")
                        {
                            SendMsg.Succeeded = true;
                            SendMsg.obj = obj;
                            cust.UserName = obj.Username;
                            this.current.customers.Remove(obj);
                            Info.window.Dispatcher.Invoke(new ThreadStart(() =>
                            {
                                try
                                {
                                    foreach (TableControl tb in Info.window.wrpLiveView.Children)
                                    {
                                        if (tb.Connection != null && tb.Connection.Equals(this))
                                        {
                                            tb.RemoveChair(cust.CustomerID);
                                            if (tb.rpChairs.Children.Count.Equals(0))
                                            {
                                                ChangeColor(Chair.Waiting.Online);
                                            }
                                            else
                                            {
                                                this.current.CustomerID = this.current.customers[current.customers.Count-1].CustomerID;
                                            }
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(ex.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
                                }
                            }), null);
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
                case enumCustomer.CustomerDelete:
                    {
                        if (error == "")
                        {
                            SendMsg.enumMethod = enumCustomer.CustomerDelete;
                            SendMsg.Succeeded = true;
                            SendMsg.obj = cust;

                        }
                        else
                        {
                            SendMsg.enumMethod = enumCustomer.CustomerDelete;
                            SendMsg.Succeeded = true;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
                case enumCustomer.CustomerGetInfo:
                    {
                        var query = cust.GetInfo();
                        SendMsg.enumMethod = enumCustomer.CustomerGetInfo;
                        SendMsg.Succeeded = true;
                        List<NCustomer> lst = new List<NCustomer>();
                        foreach (var _cust in query)
                        {
                            lst.Add(_cust.ToNCustomer());
                        }
                        SendMsg.obj = lst;
                        break;
                    }
            }
            Info.server.SendingQueue.Enqueue(SendMsg);
        }

        private void ReadBooking(Msg msg)
        {
            Booking booking = (Booking)msg.obj;
            enumBooking method = (enumBooking)msg.enumMethod;
            string error = null;
            Msg SendMsg = new Msg();
            switch (method)
            {
                case enumBooking.BookingAdd:
                    {
                        error = booking.Add();
                        SendMsg.enumMethod = enumBooking.BookingAdd;
                        if (error == "")
                        {
                            SendMsg.Succeeded = true;
                            SendMsg.obj = booking;
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
                case enumBooking.BookingCancel:
                    {
                        error = booking.Cancel();
                        SendMsg.enumMethod = enumBooking.BookingCancel;
                        if (error == "")
                        {
                            SendMsg.obj = booking;
                            SendMsg.Succeeded = true;
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
                case enumBooking.BookingDelete:
                    {
                        error = booking.Delete();
                        SendMsg.enumMethod = enumBooking.BookingDelete;
                        if (error == "")
                        {
                            SendMsg.Succeeded = true;
                            SendMsg.obj = booking;
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
                case enumBooking.BookingEdit:
                    {
                        error = booking.Edit();
                        SendMsg.enumMethod = enumBooking.BookingEdit;
                        if (error == "")
                        {
                            SendMsg.Succeeded = true;
                            SendMsg.obj = booking;
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
            }
            Info.server.SendingQueue.Enqueue(SendMsg);
        }

        private void ReadFavorite(Msg msg)
        {
            Favorite fav = (Favorite)msg.obj;
            enumFavorite method = (enumFavorite)msg.enumMethod;
            string error = null;
            Msg SendMsg = new Msg();
            switch (method)
            {
                case enumFavorite.FavoriteAdd:
                    {
                        error = fav.Add();
                        SendMsg.enumMethod = enumFavorite.FavoriteAdd;
                        if (error == "")
                        {
                            SendMsg.obj = fav;
                            SendMsg.Succeeded = true;
                        }
                        else
                        {
                            SendMsg.obj = (object)error;
                            SendMsg.Succeeded = false;
                        }
                        break;
                    }
                case enumFavorite.FavoriteDelete:
                    {
                        SendMsg.enumMethod = enumFavorite.FavoriteDelete;
                        error = fav.DeleteByCustomerIDAndMenuItemID();
                        if (error == "")
                        {
                            SendMsg.Succeeded = true;
                            SendMsg.obj = fav;
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
            }
            Info.server.SendingQueue.Enqueue(SendMsg);
        }

        private void ReadFeedback(Msg msg)
        {
            NFeedback nFeed = (NFeedback)msg.obj;
            Feedback feed = new Feedback();
            enumFeedback method = (enumFeedback)msg.enumMethod;
            string error = null;
            Msg SendMsg = new Msg();
            switch (method)
            {
                case enumFeedback.FeedbackAdd:
                    {
                        error = feed.Add();
                        SendMsg.enumMethod = enumFeedback.FeedbackAdd;
                        if (error == "")
                        {
                            SendMsg.Succeeded = true;
                            SendMsg.obj = feed;
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                            SendMsg.obj = (object)error;
                        }
                        break;
                    }
            }
            //Info.server.SendingQueue.Enqueue(SendMsg);
        }

        private void ReadMenus(Msg msg)
        {
            List<NMenus> nMenusList = new List<NMenus>();
            enumMenus method = (enumMenus)msg.enumMethod;
            Msg SendMsg = new Msg();
            SendMsg.IP = msg.IP;
            SendMsg.port = msg.port;
            switch (method)
            {
                case enumMenus.MenusSearch:
                    {
                        var menusQuery = Menus.Search();
                        SendMsg.enumMethod = enumMenus.MenusSearch;
                        if (menusQuery != null)
                        {
                            foreach (var menu in menusQuery)
                            {
                                nMenusList.Add(menu.ToNMenu());
                            }
                            SendMsg.Succeeded = true;
                            SendMsg.obj = nMenusList;
                        }
                        else
                        {
                            SendMsg.Succeeded = false;
                        }
                        break;
                    }
            }
            Info.server.SendingQueue.Enqueue(SendMsg);
        }

        private void ReadMenuItem(Msg msg)
        {
            List<NMenuItem> nMenuItemsList1 = new List<NMenuItem>();
            List<NMenuItem> nMenuItemsList2 = new List<NMenuItem>();
            List<NMenuItem> nMenuItemsList3 = new List<NMenuItem>();

            enumMenuItem method = (enumMenuItem)msg.enumMethod;

            Msg SendMsg1 = new Msg();
            Msg SendMsg2 = new Msg();
            Msg SendMsg3 = new Msg();

            SendMsg1.IP = msg.IP;
            SendMsg1.port = msg.port;

            SendMsg2.IP = msg.IP;
            SendMsg2.port = msg.port;

            SendMsg3.IP = msg.IP;
            SendMsg3.port = msg.port;
            
            switch (method)
            {
                case enumMenuItem.MenuItemsSearch:
                    {
                        SendMsg1.enumMethod = enumMenuItem.MenuItemsSearch;
                        SendMsg2.enumMethod = enumMenuItem.MenuItemsSearch;
                        SendMsg3.enumMethod = enumMenuItem.MenuItemsSearch;

                        var menuItemsQuery = MenuItem.Search();
                        if (menuItemsQuery != null)
                        {
                            List<MenuItem> lst = menuItemsQuery.ToList();

                            for (int i = 0; i < 20; i++)
                            {
                                MenuItem oppa = (MenuItem)lst[i];
                                nMenuItemsList1.Add(oppa.ToNMenuItem());
                            }
                            for (int i = 20; i < 40; i++)
                            {
                                MenuItem oppa = (MenuItem)lst[i];
                                nMenuItemsList2.Add(oppa.ToNMenuItem());
                            }
                            for (int i = 40; i < lst.Count; i++)
                            {
                                MenuItem oppa = (MenuItem)lst[i];
                                nMenuItemsList3.Add(oppa.ToNMenuItem());
                            }

                            SendMsg1.obj = nMenuItemsList1;
                            SendMsg2.obj = nMenuItemsList2;
                            SendMsg3.obj = nMenuItemsList3;
                            SendMsg1.Succeeded = true;
                            SendMsg2.Succeeded = true;
                            SendMsg3.Succeeded = true;
                        }
                        else
                        {
                            SendMsg1.Succeeded = false;
                            SendMsg2.Succeeded = false;
                            SendMsg3.Succeeded = false;
                        }
                        break;
                    }
            }
            Info.server.SendingQueue.Enqueue(SendMsg1);
            Info.server.SendingQueue.Enqueue(SendMsg2);
            Info.server.SendingQueue.Enqueue(SendMsg3);
        }

        private void ReadOrder(Msg msg)
        {
            enumOrder method = (enumOrder)msg.enumMethod;
            string error = null;
            Msg SendMsg = new Msg();
            SendMsg.IP = msg.IP;
            SendMsg.port = msg.port;
            switch (method)
            {
                case enumOrder.OrderAdd:
                    {
                        NOrder nOrder = (NOrder)msg.obj;
                        Order order = new Order(nOrder);
                        error = order.Add();
                        if (int.Parse(error) >= 0)
                        {
                            foreach (var item in nOrder.lstItems)
                            {
                                OrderMenuItem newOrderItem = new OrderMenuItem(item.Value, int.Parse(error));
                                newOrderItem.Add();
                            }
                        }
                        ShowMessage("New Order!");
                        ChangeColor(Chair.Waiting.Order);
                        SendMsg.Succeeded = true;
                        break;
                    }
                case enumOrder.OrderGet:
                    {
                        int CustomerID = (int)msg.obj;
                        Order order = new Order();
                        order.CustomerID = CustomerID;
                        List<MenuItem> NotPaidOrders = order.NotPaid();
                        List<NMenuItem> NItems = new List<NMenuItem>();
                        foreach (var item in NotPaidOrders)
                        {
                            NItems.Add(item.ToNMenuItem());
                        }
                        SendMsg.enumMethod = enumOrder.OrderGet;
                        SendMsg.obj = NItems;
                        break;
                    }
            }
            Info.server.SendingQueue.Enqueue(SendMsg);
        }

        private void ReadPersonalization(Msg msg)
        {
            enumPersonalization method = (enumPersonalization)msg.enumMethod;
            Msg SendMsg = new Msg();
            SendMsg.IP = msg.IP;
            SendMsg.port = msg.port;
            switch (method)
            {
                case enumPersonalization.GetGenres:
                    {
                        SendMsg.enumMethod = enumPersonalization.GetGenres;
                        if (Info.MusicVotes == null)
                        {
                            Info.MusicVotes = new Dictionary<Genre, int>();
                            Genre.lstGenre = Genre.Search();
                            foreach (var genre in Genre.lstGenre)
                            {
                                Info.MusicVotes.Add(genre, 0);
                            }
                        }
                        var genres = from genre in Info.MusicVotes.Keys
                                     select genre.GenreName;
                        SendMsg.obj = genres.ToList();
                        break;
                    }
                case enumPersonalization.GetACTemp:
                    {
                        SendMsg.enumMethod = enumPersonalization.GetACTemp;
                        if (Info.ACVotes == null)
                        {
                            Info.ACVotes = new Dictionary<AC, int>();
                            for (int i = 15; i <= 30; i++)
                            {
                                Info.ACVotes.Add(new AC { ID = 0, Temp = i.ToString() }, 0);
                            }
                        }
                        var ACs = from temp in Info.ACVotes.Keys
                                  select temp.Temp;
                        SendMsg.obj = ACs.ToList();
                        break;
                    }
                case enumPersonalization.GetTVChannels:
                    {
                        SendMsg.enumMethod = enumPersonalization.GetTVChannels;
                        if (Info.TVVotes == null)
                        {
                            Info.TVVotes = new Dictionary<TV, int>();
                            TV.lstTV = TV.Search();
                            foreach (var tv in TV.lstTV)
                            {
                                Info.TVVotes.Add(tv, 0);
                            }
                        }
                        var TVs = from tv in Info.TVVotes.Keys
                                  select tv.ChannelName;
                        SendMsg.obj = TVs.ToList();
                        break;
                    }
                case enumPersonalization.SendVotes:
                    {
                        NVote vote = (NVote)msg.obj;
                        SetVotes(vote);
                        ShowMessage("New Vote!");
                        break;
                    }
            }
            Info.server.SendingQueue.Enqueue(SendMsg);
        }

        private void ReadAdminTools(Msg msg)
        {
            enumAdminTools method = (enumAdminTools)msg.enumMethod;
            switch (method)
            {
                case enumAdminTools.DisableModule:
                    {
                        Dictionary<enumModules, bool> moduleOptions = AdminTools.GetModules();
                        Msg SendMsg = new Msg();
                        SendMsg.IP = msg.IP;
                        SendMsg.enumMethod = enumAdminTools.DisableModule;
                        SendMsg.port = msg.port;
                        SendMsg.obj = moduleOptions;
                        Info.server.SendingQueue.Enqueue(SendMsg);
                        break;
                    }
                case enumAdminTools.SignOutCustomer:
                    {
                        break;
                    }
                case enumAdminTools.GetStatus:
                    {
                        current = (CurrentInfo)msg.obj;
                        break;
                    }
                case enumAdminTools.LocalConnection:
                    {
                        break;
                    }
                case enumAdminTools.AdminConnection:
                    {
                        break;
                    }
            }
        }
        #endregion


        #region IEquatable<ClientConnection> Members

        public bool Equals(ClientConnection other)
        {
            //Check whether the compared object is null.
            if (Object.ReferenceEquals(other, null)) return false;

            //Check whether the compared object references the same data.
            if (Object.ReferenceEquals(this, other)) return true;

            //Check whether the products' properties are equal.
            return current.TableID.Equals(other.current.TableID);
        }

        #endregion
    }
}